﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Windows;
using System.Diagnostics;
using System.Windows.Forms;
using Demonbuddy;
using SarkothFarmer.ClassSpecifics;
using SarkothFarmer.Helpers;
using SarkothFarmer.Settings;
using Zeta;
using Zeta.Common;
using Zeta.Common.Plugins;
using Zeta.CommonBot;
using Zeta.Internals.Actors;
using MessageBox = System.Windows.Forms.MessageBox;

namespace SarkothFarmer
{
    public class Main : IPlugin
    {
        #region Iplugin
        public bool Equals(IPlugin other)
        {
            return other.Name == Name && other.Version == Version;
        }

        public string Author
        {
            get { return "Inrego"; }
        }

        public string Description
        {
            get { return "Does Sarkoth runs as fast as possible!"; }
        }

        public string Name
        {
            get { return "Sarkoth Farmer r" + settingsWrapper.CurrentRev; }
        }

        public Version Version
        {
            get { return new Version(0, settingsWrapper.CurrentRev); }
        }

        public Window DisplayWindow
        {
            get
            {
                if (settingsWindow != null && settingsWindow.Visible)
                {
                }
                else
                {
                    settingsWindow = new SettingsWindow(settingsWrapper);
                    settingsWindow.Show();
                }
                return null;
            }
        }

        /// <summary> Executes the shutdown action. This is called when the bot is shutting down. (Not when Stop() is called) </summary>
        public void OnShutdown()
        {
            
        }

        /// <summary> Executes the enabled action. This is called when the user has enabled this specific plugin via the GUI. </summary>
        public void OnEnabled()
        {
            Logger.Write("Enabled.");
        }

        /// <summary> Executes the disabled action. This is called whent he user has disabled this specific plugin via the GUI. </summary>
        public void OnDisabled()
        {
            Logger.Write("Disabled.");
        }

        #endregion

        private bool _initialized;
        private Stopwatch runTimer = new Stopwatch();
        private StateManager state;
        private SettingsWindow settingsWindow;
        public static SettingsWrapper settingsWrapper;
        public void OnInitialize()
        {
            settingsWrapper = new SettingsWrapper();
            if (settingsWrapper.Update)
                new Thread(Updater.CheckForUpdate) { IsBackground = true }.Start();
        }

        public void OnPulse()
        {
            if (!_initialized)
            {
                Logger.Write("Initializing.");
                GameEvents.OnGameLeft += new EventHandler<EventArgs>(OnGameLeft);
                GameEvents.OnGameJoined += new EventHandler<EventArgs>(OnGameJoined);
                state = new StateManager(Common.CharacterClass);
                Composites.PickupLoot = false;
                _initialized = true;
            }
            if (Zeta.CommonBot.Logic.BrainBehavior.IsVendoring)
                return;
            if (ZetaDia.Me.IsInTown && runTimer.IsRunning)
                runTimer.Stop();
            if (!ZetaDia.Me.IsInTown && !runTimer.IsRunning)
                runTimer.Start();
            if (ZetaDia.Me.IsInTown)
                return;
            // If current state is ForceLeave, only call the runstate and no other code.
            if (state.CurrentState == StateManager.State.ForceLeave)
            {
                state.RunState();
                return;
            }
            // Do nothing while moving after Sarkoth is pulled.
            if (ZetaDia.Me.Movement.IsMoving && state.CurrentState != StateManager.State.Scout && state.CurrentState != StateManager.State.Cellar)
                return;
            // Do nothing while in combat
            if (Composites.KillMonsters && Composites.IsUnitNear((int)Composites.KillRadius))
                return;
            // If run has taken too long - set state to forceleave.
            if (runTimer.ElapsedMilliseconds >= settingsWrapper.MaxTime*1000)
            {
                Logger.Write("This run has taken more than {0} seconds. Ending this game.", settingsWrapper.MaxTime);
                state.CurrentState = StateManager.State.ForceLeave;
                Logger.WriteVerbose("Switched state to {0}", state.CurrentState);
                return;
            }
            state.RunState();
        }

        public void OnGameLeft(object sender, EventArgs e)
        {
            if (runTimer.ElapsedMilliseconds > 0)
            {
                state.GetStats.AddRun(TimeSpan.FromMilliseconds(runTimer.ElapsedMilliseconds), state.Cellar);
                runTimer.Reset();
            }
            state.ResetState();
            Common.ClearBlacklist();
            Logger.WriteVerbose("Switched state to {0}", state.CurrentState);
        }
        public void OnGameJoined(object sender, EventArgs e)
        {
            state.ResetState();
            Logger.WriteVerbose("Switched state to {0}", state.CurrentState);
            runTimer.Start();
        }
    }
}